from typing import NoReturn
import numpy as np
import cv2

class Carmer:
    __frontface_cascPath = "data\\haarcascades\\haarcascade_frontalface_default.xml"
    __profileface_cascPath = "data\\haarcascades\\haarcascade_profileface.xml"
    __bieye_cascPath = "data\\haarcascades\\haarcascade_eye.xml"
    __reye_cascPath = "data\\haarcascades\\haarcascade_righteye_2splits.xml"
    __leye_cascPath = "data\\haarcascades\\haarcascade_leye_2splits.xml"
    __eyeglassCascade_eye = "data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml"
    video_local = 0
    voide_online = 'http://admin:admin@10.21.229.184:8081/video'
    def __init__(self,capID):
        # Carmer参数
        self.capture = cv2.VideoCapture(capID)
        # 人脸数据
        self.frontfaceCascade_face = cv2.CascadeClassifier(Carmer.__frontface_cascPath)
        self.profilefaceCascade_face = cv2.CascadeClassifier(Carmer.__profileface_cascPath)
        self.bieyeCascade_eye = cv2.CascadeClassifier(Carmer.__bieye_cascPath)
        self.reyeCascade_eye = cv2.CascadeClassifier(Carmer.__reye_cascPath)
        self.leyeCascade_eye = cv2.CascadeClassifier(Carmer.__leye_cascPath)
        self.geyeCascade_eye = cv2.CascadeClassifier(Carmer.__eyeglassCascade_eye)
        self.frame = None
        self.gray = None

    def frontface(self):
        return self.frontfaceCascade_face.detectMultiScale(
            self.gray,
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(30, 30)
        )


    def pfaces1(self):
        return self.profilefaceCascade_face.detectMultiScale(
            self.gray,
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(30, 30)
        )


    def pfaces2(self):
        return self.profilefaceCascade_face.detectMultiScale(
            cv2.flip(self.gray, 1),
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(30, 30)
        )


    def bieyes(self,gray_face):
        with_galss = self.geyeCascade_eye.detectMultiScale(
            gray_face,
            scaleFactor=1.1
        )
        if with_galss != ():
            return with_galss

        return self.bieyeCascade_eye.detectMultiScale(
            gray_face,
            scaleFactor=1.1
        )

    def face_detect(self):
        # 0是代表摄像头编号，只有一个的话默认为0
        ref, self.frame = self.capture.read()
        self.gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)  # 灰度转化
        front_faces = self.frontface()
        pf_faces1 = self.pfaces1()
        pf_faces2 = self.pfaces2()
        if front_faces != (): # 正侧
            for (x1, y1, w1, h1) in front_faces:
                cv2.rectangle(self.frame, (x1, y1), (x1 + w1, y1 + h1), (0, 255, 0), 2)
                gray_face = self.gray[y1:y1+h1, x1:x1+w1]
                face_color = self.frame[y1:y1+h1, x1:x1+w1]
                eyes = self.bieyes(gray_face)
                for (eye_x, eye_y, eye_w, eye_h) in eyes:
                    cv2.rectangle(face_color, (eye_x, eye_y), (eye_x+eye_w, eye_y+eye_h), (0, 255, 0), 2)
                return self.frame, eyes
        elif pf_faces1 != (): # 左侧
            for (x1, y1, w1, h1) in pf_faces1:
                cv2.rectangle(self.frame, (x1, y1), (x1 + w1, y1 + h1), (0, 255, 0), 2)
            return self.frame, pf_faces1
        elif pf_faces2 != (): # 右侧
            for (x1, y1, w1, h1) in pf_faces2:
                cv2.rectangle(self.frame, (x1, y1), (w1 - x1, y1 + h1), (0, 255, 0), 2)
            return self.frame, pf_faces2
        return self.frame, ()
    
    def release(self):
        return self.capture.release()

